package org.ssh2.core.dao.impl;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.ssh2.core.dao.IBaseDao;
import org.ssh2.core.util.Page;
import org.ssh2.core.util.ReflectionUtils;

/**
 * 公共daoimpl
 * @林景锋  
 * @2017年11月21日
 */

@Repository("baseDao")
public class BaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T> {



	@Resource(name = "sessionFactory")
	public void setSuperSessionFactory(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}

	/**
	 * 创建一个Class的对象来获取泛型的class
	 */

	private Class<T> entityClass;

	public  BaseDaoImpl() {
		// TODO Auto-generated constructor stub
		/**
		 * //获取的其ReflectionUtils的泛型类型
		 */

		this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
	}

	public BaseDaoImpl(final Class<T> entityClass){
		this.entityClass = entityClass;
	}

	public Class<T> getEntityClass(){
		return entityClass;
	}

	/**
	 * 增
	 */
	@Override
	public void save(T t) {
		this.getHibernateTemplate().save(t);
	}

	/**
	 * 删
	 */
	@Override
	public void delete(int id) {
		this.getHibernateTemplate().delete(this.load(id));
	}

	/**
	 * 改
	 */
	@Override
	public void update(T t) {
		this.getHibernateTemplate().update(t);
	}

	/**
	 * 查
	 */
	@Override
	public T load(int id) {
		return this.getHibernateTemplate().load(getEntityClass(), id);
	}

	/**
	 * 数据库中根据你的查询条件只会返回唯一结果 ,
	 * 就可以用uniqueResult这个方法
	 */
	@SuppressWarnings("unchecked")
	@Override
	public T getUniqueResult(String hql, Object... args) {
		T t = null;
		Query query = this.getSession().createQuery(hql);
		for(int i = 0;i<args.length;i++){
			query.setParameter(i, args[i]);
		}
		t = (T) query.uniqueResult();
		return t;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> list(String hql, Object... args) {

		Query query = this.getSession().createQuery(hql);
		for(int i=0;i<args.length;i++){
			query.setParameter(i, args[i]);
		}
		List<T> list = query.list();
		return list;

	}

	/**
	 * 获取一张表的的全部数据
	 */
	@SuppressWarnings({ "unchecked" })
	@Override
	public List<T> getAllFromTable() {
		String hql = "from " + getEntityClass().getSimpleName();
		Query query = this.getSession().createQuery(hql);
		List<T> list = query.list();
		return list;

	}

	/**
	 * 分页查询
	 * 通过获取页数
	 * 调用hibernate的session控制查询
	 */
	@SuppressWarnings("unchecked")
	@Override
	public boolean findForPage(Page<T> page) {

		Session session = this.getSession();
		if(page!=null){
			//查询总数
			String hql ="select count(*) from " + getEntityClass().getSimpleName();
			//long类型查询出来
			long total = (long) session.createQuery(hql).uniqueResult();
			//设置分页总记录数计算 总页数
			page.setTotal(total);
			//分页查询
			hql = "from " + getEntityClass().getSimpleName();
			Query query = session.createQuery(hql);
			//设置第一条记录的位置
			query.setFirstResult((page.getPageNo()-1)*page.getOnePageNum());
			//设置查询总记录数字
			query.setMaxResults(page.getOnePageNum());
			List<T> list = query.list();
			page.setDatas(list);
			return true;

		}else{
			return false;
		}

	}

	/**
	 * 通过条件进行分页查询condition
	 */
	@SuppressWarnings("unchecked")
	@Override
	public boolean findPageByCondition(Page<T> page, String condition) {
		Session session = this.getSession();
		if(page!=null){
			//查询总数
			String hql ="select count(*) from " + getEntityClass().getSimpleName();
			//long类型查询出来
			long total = (long) session.createQuery(hql).uniqueResult();
			//设置分页总记录数计算 总页数
			page.setTotal(total);
			//分页查询
			hql = "from " + getEntityClass() + condition;
			Query query = session.createQuery(hql);

			//设置第一条记录的位置
			query.setFirstResult((page.getPageNo()-1)*page.getOnePageNum());
			//设置查询总记录数字
			query.setMaxResults(page.getOnePageNum());
			List<T> list = query.list();
			page.setDatas(list);
			return true;
		}else{
			return false;
		}
	}

	@Override
	public void batchDelete(List<Integer> ids) {
		for(int i=0;i<ids.size();i++){
			this.delete(ids.get(i));
		}

	}

	/**
	 * 如果对象已经在本session中持久化了，不做任何事
	 * 如果另一个与本session关联的对象拥有相同的持久化标识(identifier)，抛出一个异常
	 * 如果对象没有持久化标识(identifier)属性，对其调用save()
	 * 如果对象的持久标识(identifier)表明其是一个新实例化的对象，对其调用save()
	 * 如果对象是附带版本信息的（通过<version>或<timestamp>） 并且版本属性的值表明其是一个新实例化的对象，save()它。
	 * 否则update() 这个对象
	 */
	@Override
	public void saveOrUpdate(T t) {
		this.getHibernateTemplate().saveOrUpdate(t);
	}

	public Query createQuery(final String queryString, final Object... values) {
		Query query = this.getSession().createQuery(queryString);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}

		return query;
	}
}
